#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
健康检查定时任务脚本
用法: 在 crontab 中添加 */5 * * * * /usr/bin/python3 /app/scripts/health_check.py
"""

import json
import os
import subprocess
import time
from datetime import datetime

LOG_FILE = "/app/logs/health_check.log"
HEALTH_DATA_FILE = "/app/data/health_status.json"

def log_message(message):
    """记录日志消息"""
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(LOG_FILE, "a") as f:
        f.write(f"{timestamp}: {message}\n")

def get_system_info():
    """获取系统信息"""
    try:
        # 获取系统负载
        with open('/proc/loadavg', 'r') as f:
            load_avg = f.read().strip().split()[:3]
        
        # 获取内存信息
        with open('/proc/meminfo', 'r') as f:
            mem_info = {}
            for line in f:
                if line.startswith(('MemTotal:', 'MemAvailable:', 'MemFree:')):
                    key, value = line.split(':', 1)
                    mem_info[key.strip()] = int(value.strip().split()[0])
        
        # 获取磁盘使用情况
        disk_usage = subprocess.check_output(['df', '/app'], universal_newlines=True)
        disk_lines = disk_usage.strip().split('\n')
        if len(disk_lines) > 1:
            disk_info = disk_lines[1].split()
            disk_used_percent = disk_info[4].rstrip('%')
        else:
            disk_used_percent = "0"
        
        return {
            "load_avg": load_avg,
            "memory": mem_info,
            "disk_used_percent": int(disk_used_percent)
        }
    except Exception as e:
        log_message(f"获取系统信息失败: {e}")
        return None

def check_services():
    """检查服务状态"""
    services = {}
    
    # 检查HTTP服务是否响应
    try:
        result = subprocess.run(['curl', '-s', '-o', '/dev/null', '-w', '%{http_code}', 'http://localhost:8080'], 
                               capture_output=True, text=True, timeout=5)
        services['http_server'] = result.returncode == 0 and result.stdout == '200'
    except:
        services['http_server'] = False
    
    # 检查cron服务
    try:
        result = subprocess.run(['pgrep', 'crond'], capture_output=True, text=True)
        services['cron'] = result.returncode == 0
    except:
        services['cron'] = False
    
    return services

def save_health_data(data):
    """保存健康数据到JSON文件"""
    try:
        os.makedirs(os.path.dirname(HEALTH_DATA_FILE), exist_ok=True)
        with open(HEALTH_DATA_FILE, 'w') as f:
            json.dump(data, f, indent=2)
    except Exception as e:
        log_message(f"保存健康数据失败: {e}")

def main():
    """主函数"""
    log_message("开始健康检查")
    
    # 获取系统信息
    system_info = get_system_info()
    if not system_info:
        log_message("健康检查失败: 无法获取系统信息")
        return
    
    # 检查服务状态
    services = check_services()
    
    # 创建健康报告
    health_data = {
        "timestamp": datetime.now().isoformat(),
        "system": system_info,
        "services": services,
        "status": "healthy" if all(services.values()) else "warning"
    }
    
    # 保存健康数据
    save_health_data(health_data)
    
    # 记录日志
    status = health_data["status"]
    load_avg = system_info["load_avg"][0]
    disk_usage = system_info["disk_used_percent"]
    
    log_message(f"健康检查完成: 状态={status}, 负载={load_avg}, 磁盘使用={disk_usage}%")
    
    # 如果有警告，记录详细信息
    if status == "warning":
        failed_services = [name for name, status in services.items() if not status]
        log_message(f"警告: 以下服务异常: {', '.join(failed_services)}")

if __name__ == "__main__":
    main() 